package com.yzt.plugin_imageloader;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.NinePatch;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.vectordrawable.graphics.drawable.Animatable2Compat;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.load.engine.cache.ExternalCacheDiskCacheFactory;
import com.bumptech.glide.load.engine.cache.InternalCacheDiskCacheFactory;
import com.bumptech.glide.load.resource.gif.GifDrawable;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.request.target.ViewTarget;
import com.bumptech.glide.request.transition.Transition;
import com.yzt.p_base.utils.FileUtils;
import com.yzt.plugin_imageloader.trans.GlideBlurTransformation;

import java.io.File;

/**
 * author : bob
 * date   : 2022/11/29
 * desc   :
 */
public class ImageLoadUtil {
    /**
     * 图片加载
     *
     * @param url 路径
     * @param iv  显示控件
     */
    public static void loadAvatar(Context mContext, String url, ImageView iv) {
        setIvWandH(url, iv);
        loadAvatarSmall(mContext, url, iv);
    }

    /**
     * 图片加载
     *
     * @param url         路径
     * @param iv          显示控件
     * @param placeholder 默认图
     */
    public static void loadAvatar(Context mContext, String url, ImageView iv, int placeholder) {
        if (isDestroy(mContext)) {
            return;
        }
        url = setIvWandH(url, iv);
        if (requestOptions == null) {
            requestOptions = new RequestOptions();
            requestOptions.placeholder(placeholder);
            requestOptions.error(placeholder);
            requestOptions.override(-1, -1).diskCacheStrategy(DiskCacheStrategy.ALL).centerCrop();
        }
        iv.setBackgroundColor(Color.TRANSPARENT);

        Glide.with(mContext).load(url).apply(requestOptions).into(iv);
    }

    /**
     * 图片地址是否带参数
     */
    private static boolean isParams(String url) {
        if (TextUtils.isEmpty(url)) {
            return false;
        }
        return url.contains("?");
    }

    /**
     * 将图片url转为web格式的url
     */
    public static String url2webp(String url, int withPX) {
        if (withPX > 0 && !TextUtils.isEmpty(url) && url.contains("qn-video")) {
            if (url.contains("?")) {
                url = url.substring(0, url.indexOf("?"));
            }
            url = url + "?imageView2/0/format/webp/w/" + withPX;
        }
        return url;
    }

    public static String url2Webp(String url) {
        if (!TextUtils.isEmpty(url) && url.contains("qn-video")) {
            if (url.contains("?")) {
                url = url.substring(0, url.indexOf("?"));
            }
            url = url + "?imageView2/0/format/webp";
        }
        return url;
    }

    public static RequestOptions requestOptions;

    /**
     * 图片加载
     */
    public static void loadAvatarSmall(Context mContext, String url, ImageView iv) {
        if (isDestroy(mContext)) {
            return;
        }
        url = setIvWandH(url, iv);
        if (requestOptions == null) {
            requestOptions = new RequestOptions();
            requestOptions.placeholder(R.drawable.default_photo);
            requestOptions.error(R.drawable.default_photo);
            requestOptions.override(-1, -1).diskCacheStrategy(DiskCacheStrategy.ALL).centerCrop();
        }
        iv.setBackgroundColor(Color.TRANSPARENT);

        Glide.with(mContext).load(url).apply(requestOptions).into(iv);
    }

    /**
     * 图片加载
     *
     * @param url 路径
     * @param iv  显示控件
     */
    public static void loadIv(Context mContext, String url, ImageView iv) {
        if (isDestroy(mContext)) {
            return;
        }
        loadIv(mContext, url, iv, R.drawable.transparent_bg, -1, -1);
    }

    /**
     * 带加载图的头像
     */
    public static void loadImg(Context mContext, String url, ImageView iv) {
        if (isDestroy(mContext)) {
            return;
        }
        Glide.with(mContext).load(url).placeholder(R.drawable.default_photo).error(R.drawable.default_photo).into(iv);
    }

    private static String setIvWandH(String url, ImageView iv) {
        int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        iv.measure(w, h);
        int height = iv.getMeasuredHeight();
        int width = iv.getMeasuredWidth();
        if (height > 0 && width > 0 && !isParams(url)) {
            url = url + "?imageslim";
        }
        return url;
    }


    public static void loadIv(Context mContext, int id, ImageView iv) {
        if (isDestroy(mContext)) {
            return;
        }
        RequestOptions requestOptions = new RequestOptions()
                .centerCrop()
                .placeholder(R.drawable.transparent_bg)
                .error(R.drawable.transparent_bg).diskCacheStrategy(DiskCacheStrategy.ALL);

        Glide.with(mContext).load(id).apply(requestOptions).into(iv);
    }

    public static void setBackground4NinePath(Context mContext, View view, File file, int defaultDrawable) {
        if (isDestroy(mContext)) {
            return;
        }
        if (null == file) {
            return;
        }
        try {
            Bitmap bitmap = BitmapFactory.decodeFile(file.getPath());
            if (bitmap != null) {
                Rect rect = new Rect();
                Drawable drawable = getNinePatchDrawable(bitmap, mContext, rect);

                if (drawable != null) {
                    view.setBackground(drawable);
                    view.setPadding(rect.left, rect.top, rect.right, rect.bottom);
                } else {
                    view.setBackground(mContext.getResources().getDrawable(defaultDrawable));
                }
            }
        } catch (Exception ignored) {
        }
    }

    public static void load9Png(Context mContext, String url, int defaultDrawable, View tv) {
        if (isDestroy(mContext)) {
            return;
        }
        try {
            Glide.with(mContext).asFile()
                    .load(url)
                    .override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL).into(new CustomTarget<File>() {
                        @Override
                        public void onResourceReady(@NonNull File resource, @Nullable Transition<? super File> transition) {
                            setBackground4NinePath(mContext, tv, resource, defaultDrawable);
                        }

                        @Override
                        public void onLoadCleared(@Nullable Drawable placeholder) {

                        }

                        @Override
                        public void onLoadFailed(@Nullable Drawable errorDrawable) {
                            super.onLoadFailed(errorDrawable);
                        }
                    });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static Drawable getNinePatchDrawable(Bitmap bitmap, Context context, Rect rect) {
        if (isDestroy(context)) {
            return null;
        }
        if (bitmap == null) {
            return null;
        }
        byte[] chunk = bitmap.getNinePatchChunk();
        NinePatchDrawable ninePatchDrawable = null;
        if (NinePatch.isNinePatchChunk(chunk)) {
            Rect mPaddings = NinePatchChunk.deserialize(chunk).mPadding;

            //默认的padding进入drawable中会经过密度适配，我们不需要，所以要重新在设置padding
            ninePatchDrawable = new NinePatchDrawable(context.getResources(), bitmap, chunk, mPaddings, null);
            if (null != mPaddings && null != rect) {
                rect.left = mPaddings.left;
                rect.right = mPaddings.right;
                rect.top = mPaddings.top;
                rect.bottom = mPaddings.bottom;
            }
        } else {
            return new BitmapDrawable(context.getResources(), bitmap);
        }
        return ninePatchDrawable;
    }

    public static void loadIvNoType(Context mContext, String url, ImageView iv, int defaultIv) {
        if (isDestroy(mContext)) {
            return;
        }
        setIvWandH(url, iv);
        RequestOptions requestOptions = new RequestOptions()
                .placeholder(defaultIv)
                .error(defaultIv).diskCacheStrategy(DiskCacheStrategy.ALL);

        Glide.with(mContext).load(url).apply(requestOptions).into(iv);
    }

    public static void loadIvNoType(Context mContext, String url, ImageView iv) {
        if (isDestroy(mContext)) {
            return;
        }
        setIvWandH(url, iv);
        loadIvNoType(mContext, url, iv, R.drawable.transparent_bg);
    }

    public static void loadIv(Context mContext, String url, ImageView iv, int id) {
        if (isDestroy(mContext)) {
            return;
        }
        try {
            setIvWandH(url, iv);
            RequestOptions requestOptions = new RequestOptions()
                    .placeholder(id)
                    .error(id)
                    .centerCrop()
                    .dontAnimate();
            iv.setBackgroundColor(Color.TRANSPARENT);

            Glide.with(mContext).load(url).apply(requestOptions).into(iv);
        } catch (Exception e) {
            Log.e("gz-error", "ImageLoadUtil::errorMsg=>" + e.getMessage());
        }
    }

    /**
     * 不走缓存
     */
    public static void loadIvNoCache(Context mContext, String url, ImageView iv) {
        if (isDestroy(mContext)) {
            return;
        }
        setIvWandH(url, iv);
        RequestOptions requestOptions = RequestOptions
                .centerCropTransform()
                .diskCacheStrategy(DiskCacheStrategy.NONE)
                .skipMemoryCache(true);

        iv.setBackgroundColor(Color.TRANSPARENT);
        Glide.with(mContext).load(url).apply(requestOptions).into(iv);
    }


    /**
     * 图片加载
     *
     * @param url       路径
     * @param iv        显示控件
     * @param defaultIv 默认图片
     */
    @SuppressLint("CheckResult")
    public static void loadIv(Context mContext, String url, ImageView iv, int defaultIv, int with, int height) {
        if (isDestroy(mContext)) {
            return;
        }
        if (TextUtils.isEmpty(url)) {
            url = "https://";
        }
        RequestOptions requestOptions = new RequestOptions();
        if (defaultIv > 0) {
            requestOptions.placeholder(defaultIv);
            requestOptions.error(defaultIv);
        }

        iv.setBackgroundColor(Color.TRANSPARENT);
        requestOptions.override(with, height).diskCacheStrategy(DiskCacheStrategy.ALL).centerCrop();
        Glide.with(mContext).load(url).apply(requestOptions).into(iv);
    }

    /**
     * 加载圆形图片
     *
     * @param url       路径
     * @param iv        显示控件
     * @param defaultIv 默认图片
     */
    @SuppressLint("CheckResult")
    public static void loadCircle(Context mContext, String url, ImageView iv, int defaultIv) {
        loadCircle(mContext, null, url, iv, defaultIv);
    }

    /**
     * 加载圆形图片
     *
     * @param requestOptions 配置
     * @param url            路径
     * @param iv             显示控件
     * @param defaultIv      默认图片
     */
    @SuppressLint("CheckResult")
    private static void loadCircle(Context mContext, RequestOptions requestOptions, String url, ImageView iv, int defaultIv) {
        if (isDestroy(mContext)) {
            return;
        }
        setIvWandH(url, iv);
        if (TextUtils.isEmpty(url)) {
            url = "https://";
        }

        if (requestOptions == null) {
            requestOptions = new RequestOptions().circleCrop();
        }

        if (defaultIv > 0) {
            requestOptions.placeholder(defaultIv);
            requestOptions.error(defaultIv);
        }

        iv.setBackgroundColor(Color.TRANSPARENT);
        requestOptions.diskCacheStrategy(DiskCacheStrategy.ALL);

        Glide.with(mContext).load(url).apply(requestOptions).into(iv);
        iv.setBackgroundColor(Color.TRANSPARENT);
    }

    /**
     * 加载显示gif格式图片
     *
     * @param url 路径
     * @param iv  显示的控件
     */
    public static void LoadGifIv(Context mContext, String url, ImageView iv) {
        if (isDestroy(mContext)) {
            return;
        }
        if (TextUtils.isEmpty(url)) {
            url = "https://";
        }
        Glide.with(mContext).asGif().diskCacheStrategy(DiskCacheStrategy.DATA).load(url).into(iv);
    }

    /**
     * 加载显示gif格式图片
     *
     * @param id 路径
     * @param iv 显示的控件
     */
    public static void LoadGifIv(Context mContext, int id, ImageView iv) {
        if (isDestroy(mContext)) {
            return;
        }
        if (id == 0) {
            return;
        }
        Glide.with(mContext).asGif().load(id).into(iv);
    }

    /**
     * 加载动画一次
     */
    public static void loadGifIvOnce(Context mContext, String url, ImageView iv, OnAnimationStatus mOnAnimationStatus) {
        if (isDestroy(mContext)) {
            return;
        }
        Glide.with(mContext).load(url)
                .listener(new RequestListener<Drawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                        try {
                            GifDrawable drawable = (GifDrawable) resource;
                            drawable.setLoopCount(1);//只播放一次
                            drawable.registerAnimationCallback(new Animatable2Compat.AnimationCallback() {
                                @Override
                                public void onAnimationStart(Drawable drawable) {
                                    super.onAnimationStart(drawable);
                                    if (mOnAnimationStatus != null) {
                                        mOnAnimationStatus.onAnimationStart();
                                    }
                                }

                                @Override
                                public void onAnimationEnd(Drawable drawable) {
                                    super.onAnimationEnd(drawable);
                                    if (mOnAnimationStatus != null) {
                                        mOnAnimationStatus.onAnimationEnd();
                                    }
                                }
                            });
                        } catch (ClassCastException e) {
                            e.printStackTrace();
                        }
                        return false;
                    }
                }).into(iv);
    }

    public interface OnAnimationStatus {

        void onAnimationStart();

        void onAnimationEnd();
    }

    public static void loadBlur(Context mContext, String url, ImageView imageView) {
        if (isDestroy(mContext)) {
            return;
        }
        Glide.with(mContext)
                .load(url)
                .apply(RequestOptions.bitmapTransform(new GlideBlurTransformation(mContext.getApplicationContext())))
                .into(new ViewTarget<ImageView, Drawable>(imageView) {
                    @Override
                    public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
                        Drawable current = resource.getCurrent();
                        //设置图片
                        imageView.setImageDrawable(current);
                    }
                });
    }

    public static void loadBlurScan(Context mContext, String url, ImageView imageView) {
        if (isDestroy(mContext)) {
            return;
        }
        Glide.with(mContext)
                .load(url)
                .apply(RequestOptions.bitmapTransform(new GlideBlurTransformation(mContext.getApplicationContext())))

                .into(new ViewTarget<ImageView, Drawable>(imageView) {
                    @Override
                    public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
                        Drawable current = resource.getCurrent();
                        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
                        imageView.setImageDrawable(current);
                    }
                });
    }

    /**
     * 加载动画一次
     */
    public static void loadGifForever(Context mContext, String url, ImageView iv) {
        if (isDestroy(mContext)) {
            return;
        }
        Glide.with(mContext).load(url)
                .listener(new RequestListener<Drawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                        try {
                            ((GifDrawable) resource).setLoopCount(-1);//循环播放
                            // 计算动画时长
                            GifDrawable drawable = (GifDrawable) resource;
                            drawable.registerAnimationCallback(new Animatable2Compat.AnimationCallback() {
                                @Override
                                public void onAnimationStart(Drawable drawable) {
                                    super.onAnimationStart(drawable);
                                }

                                @Override
                                public void onAnimationEnd(Drawable drawable) {
                                    super.onAnimationEnd(drawable);
                                }
                            });
                        } catch (ClassCastException e) {
                            e.printStackTrace();
                        }
                        return false;
                    }
                }).into(iv);
    }

    /**
     * 加载动画一次
     */
    public static void loadGifForever(Context mContext, int drawableId, ImageView iv) {
        if (isDestroy(mContext)) {
            return;
        }
        Glide.with(mContext).load(drawableId)
                .listener(new RequestListener<Drawable>() {
                    @Override
                    public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                        try {
                            ((GifDrawable) resource).setLoopCount(-1);//只播放一次
                            // 计算动画时长
                            GifDrawable drawable = (GifDrawable) resource;
                            drawable.registerAnimationCallback(new Animatable2Compat.AnimationCallback() {
                                @Override
                                public void onAnimationStart(Drawable drawable) {
                                    super.onAnimationStart(drawable);
                                }

                                @Override
                                public void onAnimationEnd(Drawable drawable) {
                                    super.onAnimationEnd(drawable);
                                }
                            });
                        } catch (ClassCastException e) {
                            e.printStackTrace();
                        }
                        return false;
                    }
                }).into(iv);
    }

    private static void clearImageDiskCache(Context context) {
        try {
            if (Looper.myLooper() == Looper.getMainLooper()) {
                new Thread(() -> Glide.get(context).clearDiskCache()).start();
            } else {
                Glide.get(context).clearDiskCache();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 清除图片内存缓存
     */
    private static void clearImageMemoryCache(Context context) {
        try {
            if (Looper.myLooper() == Looper.getMainLooper()) { //只能在主线程执行
                Glide.get(context).clearMemory();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 清除图片所有缓存
     */
    public static void clearImageAllCache(Context context) {
        clearImageDiskCache(context);
        clearImageMemoryCache(context);
        String ImageExternalCatchDir = context.getExternalCacheDir() + ExternalCacheDiskCacheFactory.DEFAULT_DISK_CACHE_DIR;
        FileUtils.deleteFolderFile(ImageExternalCatchDir, true);
    }


    public static long getCacheSizeByte(Context context) {
        return FileUtils.getFolderSize(new File(context.getCacheDir() + "/" + InternalCacheDiskCacheFactory.DEFAULT_DISK_CACHE_DIR));
    }

    /**
     * 加载图片
     */
    public static void load(Context mContext, String url, ImageView iv) {
        if (isDestroy(mContext)) {
            return;
        }
        Glide.with(mContext).load(url).into(iv);
    }

    public static void load(Context mContext, String url, ImageView iv, int defaultId) {
        if (isDestroy(mContext)) {
            return;
        }
        RequestOptions requestOptions = new RequestOptions().diskCacheStrategy(DiskCacheStrategy.ALL);
        Glide.with(mContext)
                .load(url)
                .apply(requestOptions)
                .error(defaultId)
                .placeholder(defaultId)
                .into(iv);
    }

    /**
     * 加载图片
     */
    public static void load(Context mContext, Integer resourceId, ImageView iv) {
        if (isDestroy(mContext)) {
            return;
        }
        Glide.with(mContext).load(resourceId).into(iv);
    }

    /**
     * 获取图片drawable
     */
    public static void load4Drawable(Context context, String url, ImageRequestListener listener) {
        load4Drawable(context, url, -1, -1, listener);
    }

    /**
     * 获取图片drawable
     */
    public static void load4Drawable(Context context, String url, int width, int height, ImageRequestListener listener) {
        if (isDestroy(context)) {
            return;
        }

        RequestOptions options = new RequestOptions().override(width, height);
        load4Drawable(context, url, options, listener);
    }

    /**
     * 获取图片drawable(圆形)
     */
    public static void load4DrawableCircle(Context context, int resId, int width, int height, ImageRequestListener listener) {
        if (isDestroy(context)) {
            return;
        }

        RequestOptions options = new RequestOptions().override(width, height).circleCrop();
        load4Drawable(context, resId, options, listener);
    }

    private static void load4Drawable(Context context, String url, RequestOptions options, ImageRequestListener listener) {
        Glide.with(context).load(url)
                .apply(options)
                .into(new CustomTarget<Drawable>() {
                    @Override
                    public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
                        listener.onResourceReady(resource);
                    }

                    @Override
                    public void onLoadCleared(@Nullable Drawable placeholder) {

                    }

                    @Override
                    public void onLoadFailed(@Nullable Drawable errorDrawable) {
                        listener.onError();
                    }
                });
    }

    private static void load4Drawable(Context context, int resId, RequestOptions options, ImageRequestListener listener) {
        Glide.with(context).load(resId)
                .apply(options)
                .into(new CustomTarget<Drawable>() {
                    @Override
                    public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
                        listener.onResourceReady(resource);
                    }

                    @Override
                    public void onLoadCleared(@Nullable Drawable placeholder) {

                    }

                    @Override
                    public void onLoadFailed(@Nullable Drawable errorDrawable) {
                        listener.onError();
                    }
                });
    }

    public static void clearMemory(Context context) {
        Glide.get(context).clearMemory();
    }

    public static void trimMemory(Context context, int trimLevel) {
        Glide.get(context).trimMemory(trimLevel);
    }

    public interface ImageRequestListener {

        void onResourceReady(@NonNull Drawable resource);

        void onError();
    }

    /**
     * 判断Activity是否Destroy
     */
    public static boolean isDestroy(Context mActivity) {
        if (mActivity == null) {
            return true;
        }
        if (mActivity instanceof Activity) {
            return ((Activity) mActivity).isFinishing() || ((Activity) mActivity).isDestroyed();
        }
        return false;
    }
}
